﻿using System;
using System.Collections.Generic;

namespace innovations.util.collections
{
    public abstract class LimitedCapacityLinkedList<T> : LimitedCapacityCollection<T>
    {
        protected LimitedCapacityLinkedList() { }

        public Node<T> AddFirst(T item, string title)
        {
            Node<T> node = new Node<T>(item, title);
            node.Previous = null;
            node.Next = FirstNode;
            FirstNode = node;
            if (base.Count == 0)
                LastNode = node;
            else
                node.Next.Previous = node;
            base.Insert(0, item);
            return node;
        }

        public Node<T> RemoveFirst()
        {
            Node<T> oldFirstNode = FirstNode;
            FirstNode = FirstNode.Next;
            FirstNode.Previous = null;
            oldFirstNode.Next = null;
            base.RemoveAt(0);
            if (base.Count == 0)
            {
                FirstNode = null;
                LastNode = null;
                oldFirstNode.Previous = null;
            }
            return oldFirstNode;
        }

        public Node<T> AddLast(T item, string title)
        {
            Node<T> node = new Node<T>(item, title);
            node.Previous = LastNode;
            node.Next = null;
            LastNode = node;
            if (base.Count == 0)
            {
                node.Previous = null;
                FirstNode = node;
            }
            else if (base.Count == 1)
                FirstNode.Next = node;
            else
                LastNode.Next = node;
            base.Add(item);
            return node;
        }

        public Node<T> RemoveLast()
        {
            Node<T> oldLastNode = LastNode;
            LastNode.Previous.Next = null;
            LastNode = LastNode.Previous;
            oldLastNode.Previous = null;
            base.RemoveAt(Count - 1);
            if (base.Count == 0)
                FirstNode = null;
            return oldLastNode;
        }


        public Node<T> FirstNode { get; set; }
        public Node<T> LastNode { get; set; }
    }
}
